package com.ruoyi.bl.tools;


import com.aliyun.bailian20231229.models.AddFileResponse;
import com.aliyun.bailian20231229.models.ApplyFileUploadLeaseResponse;
import com.aliyun.bailian20231229.models.ApplyFileUploadLeaseResponseBody;
import com.aliyun.tea.TeaException;
import com.ruoyi.common.core.domain.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.DataOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Map;

/**
 * 文档上传功能
 * * @Author: 张浩
 * 将文档上传到知识库
 */


@CrossOrigin(origins = "*")
@Slf4j
@RestController
@RequestMapping("/aliyun")
public class FileUpload {
    static String FileUploadLeaseId;
    static String FileUploadUrl;
    static String fileId;
    static String ContentType;
    static String Xbailianextra;
    static com.aliyun.bailian20231229.Client client;

    static {
        try {
            client = createClient();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static com.aliyun.bailian20231229.Client createClient() throws Exception {
        // 工程代码泄露可能会导致 AccessKey 泄露，并威胁账号下所有资源的安全性。以下代码示例仅供参考。
        // 建议使用更安全的 STS 方式，更多鉴权访问方式请参见：https://help.aliyun.com/document_detail/378657.html。
        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
                // 必填，请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID。
                .setAccessKeyId("LTAI5tCVdykEfKy68Huo43qq")
                // 必填，请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
                .setAccessKeySecret("LUq5TPaynzWxYeQDlaIkoz1qgKa2Fs");
        // Endpoint 请参考 https://api.aliyun.com/product/bailian
        config.endpoint = "bailian.cn-beijing.aliyuncs.com";
        return new com.aliyun.bailian20231229.Client(config);
    }

    //申请文档上传租约
    public void ApplyFileUploadLease(MultipartFile file) throws Exception {
        if (file.isEmpty()) {
            throw new RuntimeException("文件为空");
        }
        com.aliyun.bailian20231229.models.ApplyFileUploadLeaseRequest applyFileUploadLeaseRequest = new com.aliyun.bailian20231229.models.ApplyFileUploadLeaseRequest()
                .setMd5(DigestUtils.md5DigestAsHex(file.getInputStream()))
                .setFileName(file.getOriginalFilename())
                .setSizeInBytes(String.valueOf(file.getSize()));
        com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
        java.util.Map<String, String> headers = new java.util.HashMap<>();
        try {
            ApplyFileUploadLeaseResponse result = client.applyFileUploadLeaseWithOptions(
                    "cate_6b18c99c16334b2e9a6ce2b9187f0db5_10544612",//不同类目:政策,活动
                    "llm-tt1zzffjohw0mige",//工作空间
                    applyFileUploadLeaseRequest,
                    headers,
                    runtime
            );
            ApplyFileUploadLeaseResponseBody.ApplyFileUploadLeaseResponseBodyData data = result.getBody().getData();
            FileUploadLeaseId = data.fileUploadLeaseId;
            System.out.println("FileUploadLeaseId:" + FileUploadLeaseId);
            FileUploadUrl = result.getBody().getData().getParam().url;
            System.out.println("FileUploadUrl:" + FileUploadUrl);
            System.out.println(data.getParam().getHeaders());
            Map<String, String> headers1 = (Map<String, String>) data.getParam().getHeaders();
            Xbailianextra = headers1.get("X-bailian-extra");
            ContentType = headers1.get("Content-Type");
            System.out.println("申请文档上传租约");
            UploadFile(file);
        } catch (TeaException error) {
            // 此处仅做打印展示，请谨慎对待异常处理，在工程项目中切勿直接忽略异常。
            // 错误 message
            System.out.println(error.getMessage());
            // 诊断地址
            System.out.println(error.getData().get("Recommend"));
            com.aliyun.teautil.Common.assertAsString(error.message);
        } catch (Exception _error) {
            TeaException error = new TeaException(_error.getMessage(), _error);
            // 此处仅做打印展示，请谨慎对待异常处理，在工程项目中切勿直接忽略异常。
            // 错误 message
            System.out.println(error.getMessage());
            // 诊断地址
            System.out.println(error.getData().get("Recommend"));
            com.aliyun.teautil.Common.assertAsString(error.message);
        }
    }

    //第二步:上传文档
    public void UploadFile(MultipartFile file) throws Exception {
        String preSignedUrlOrHttpUrl = FileUploadUrl;
        uploadFile(preSignedUrlOrHttpUrl, file);
        AddFile();
    }

    public static void uploadFile(String preSignedUrl, MultipartFile file) {
        HttpURLConnection connection = null;
        try {
            // 创建URL对象
            URL url = new URL(preSignedUrl);
            connection = (HttpURLConnection) url.openConnection();
            // 设置请求方法用于文档上传，需与您在上一步中调用ApplyFileUploadLease接口实际返回的Data.Param中Method字段的值一致
            connection.setRequestMethod("PUT");
            // 允许向connection输出，因为这个连接是用于上传文档的
            connection.setDoOutput(true);
            connection.setRequestProperty("X-bailian-extra", Xbailianextra);
            connection.setRequestProperty("Content-Type", ContentType);
            // 上传文件内容
            try (DataOutputStream outStream = new DataOutputStream(connection.getOutputStream());
                 InputStream fileInputStream = file.getInputStream()) {
                byte[] buffer = new byte[4096];
                int bytesRead;
                while ((bytesRead = fileInputStream.read(buffer)) != -1) {
                    outStream.write(buffer, 0, bytesRead);
                }
                outStream.flush();
            }
            // 检查响应
            int responseCode = connection.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK) {
                System.out.println("文件上传成功");
            } else {
                System.out.println("文件上传失败，响应码：" + responseCode);
                throw new RuntimeException("文件上传失败，响应码：" + responseCode);
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("文件上传失败：" + e.getMessage());
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
        }
    }

    //第三步:添加文档
    public void AddFile() throws Exception {
        com.aliyun.bailian20231229.models.AddFileRequest addFileRequest = new com.aliyun.bailian20231229.models.AddFileRequest()
                .setLeaseId(FileUploadLeaseId)
                .setParser("DASHSCOPE_DOCMIND")
                .setCategoryId("cate_6b18c99c16334b2e9a6ce2b9187f0db5_10544612");//类目
        com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
        java.util.Map<String, String> headers = new java.util.HashMap<>();
        try {
            // 复制代码运行请自行打印 API 的返回值
            AddFileResponse addFileResponse = client.addFileWithOptions("llm-tt1zzffjohw0mige", addFileRequest, headers, runtime);
            fileId = addFileResponse.getBody().getData().fileId;
            System.out.println("fileId:" + fileId);
            System.out.println("添加文档到数据管理");
        } catch (TeaException error) {
            // 此处仅做打印展示，请谨慎对待异常处理，在工程项目中切勿直接忽略异常。
            // 错误 message
            System.out.println(error.getMessage());
            // 诊断地址
            System.out.println(error.getData().get("Recommend"));
            com.aliyun.teautil.Common.assertAsString(error.message);
        } catch (Exception _error) {
            TeaException error = new TeaException(_error.getMessage(), _error);
            // 此处仅做打印展示，请谨慎对待异常处理，在工程项目中切勿直接忽略异常。
            // 错误 message
            System.out.println(error.getMessage());
            // 诊断地址
            System.out.println(error.getData().get("Recommend"));
            com.aliyun.teautil.Common.assertAsString(error.message);
        }
    }

    //第四步:提交知识库
    @PostMapping("/fileupload")
    public R<String> SubmitIndexAddDocumentsJob(@RequestParam("file") MultipartFile file) throws Exception {
        ApplyFileUploadLease(file);
        com.aliyun.bailian20231229.models.SubmitIndexAddDocumentsJobRequest submitIndexAddDocumentsJobRequest = new com.aliyun.bailian20231229.models.SubmitIndexAddDocumentsJobRequest()
                .setIndexId("ffxh57kcvi")//知识库id
                .setSourceType("DATA_CENTER_FILE")
                .setDocumentIds(java.util.Arrays.asList(
                        fileId
                ));
        com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
        java.util.Map<String, String> headers = new java.util.HashMap<>();
        try {
            // 复制代码运行请自行打印 API 的返回值
            client.submitIndexAddDocumentsJobWithOptions("llm-tt1zzffjohw0mige", submitIndexAddDocumentsJobRequest, headers, runtime);
            System.out.println("提交知识库");
            return R.ok("提交知识库成功");
        } catch (TeaException error) {
            // 此处仅做打印展示，请谨慎对待异常处理，在工程项目中切勿直接忽略异常。
            // 错误 message
            System.out.println(error.getMessage());
            // 诊断地址
            System.out.println(error.getData().get("Recommend"));
            com.aliyun.teautil.Common.assertAsString(error.message);
        } catch (Exception _error) {
            TeaException error = new TeaException(_error.getMessage(), _error);
            // 此处仅做打印展示，请谨慎对待异常处理，在工程项目中切勿直接忽略异常。
            // 错误 message
            System.out.println(error.getMessage());
            // 诊断地址
            System.out.println(error.getData().get("Recommend"));
            com.aliyun.teautil.Common.assertAsString(error.message);
        }
        return R.fail("提交知识库失败");
    }
}
